﻿using System;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Protocol;
using SuperSocket.Facility.Protocol;
using System.Collections.Generic;
using System.Net;
using SuperSocket.Common;
using SuperSocket.SocketBase.Command;
using System.Linq;

public class Client
{
    public static int index = 0;
    public static int Main(String[] args)
    {
        MyApp app = new MyApp();
        app.Setup(2012);
        app.Start();
        Console.WriteLine("server is open");
        Console.ReadLine();

        return 0;
    }

}

public class V : CommandBase<MySession, BinaryRequestInfo>
{
    public override void ExecuteCommand(MySession session, BinaryRequestInfo requestInfo)
    {
        //Console.WriteLine(Client.index++);
       session.AppServer.GetAllSessions().AsParallel().ForAll(p => p.Send(requestInfo.Body)); 
    }
}
public class MyApp : AppServer<MySession, BinaryRequestInfo>
{
    public MyApp() : base(new MyFilterFactory()) {
        this.NewSessionConnected += MyApp_NewSessionConnected;
    }

    private void MyApp_NewSessionConnected(MySession session)
    {
        Console.WriteLine($"new connection by:{session.RemoteEndPoint.Address}:{session.RemoteEndPoint.Port}  date:{DateTime.Now}");
    }
}

public class MyFilterFactory : IReceiveFilterFactory<BinaryRequestInfo>
{
    public IReceiveFilter<BinaryRequestInfo> CreateFilter(IAppServer appServer, IAppSession appSession, IPEndPoint remoteEndPoint)
    {
        return new MyReceiveFilter(3);
    }
}

public class MySession : AppSession<MySession, BinaryRequestInfo>
{
    public void Send(byte[] data)
    {
        TrySend(data, 0, data.Length);
    }
}


class MyReceiveFilter : FixedHeaderReceiveFilter<BinaryRequestInfo>
{
    public MyReceiveFilter(int headerSize) : base(headerSize) { }

    protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)
    {
        return BitConverter.ToUInt16(header, offset + 1) + 1;
    }

    protected override BinaryRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length)
    {
        //var data = bodyBuffer.CloneRange(offset - header.Count, length + header.Count);
        var data = new List<byte>();
        data.AddRange(header.Array);
        data.AddRange(bodyBuffer.CloneRange(offset, length));
        return new BinaryRequestInfo("V", data.ToArray());
    }
}